package com.imooc.coupon.executor.impl;

import com.alibaba.fastjson.JSON;
import com.imooc.coupon.constant.CouponCategory;
import com.imooc.coupon.constant.RuleFlag;
import com.imooc.coupon.executor.AbstractExecutor;
import com.imooc.coupon.executor.RuleExecutor;
import com.imooc.coupon.vo.GoodsInfo;
import com.imooc.coupon.vo.SettlementInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.sql.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.stream.Collectors;

//满减 + 折扣优惠券结算规则执行器
@Slf4j
@Component
public class ManjianZheKouExecutor extends AbstractExecutor implements RuleExecutor {
    @Override
    public RuleFlag ruleConfig() {
        return RuleFlag.MANJIAN_ZHEKOU;
    }

    @Override
    @SuppressWarnings("all")
    protected boolean isGoodsTypeSatisfy(SettlementInfo settlement) {
        log.debug("Check Manjain And ZheKou Is Match Or Not !");
        List<Integer> goodsType = settlement.getGoodsInfos().stream()
                .map(GoodsInfo::getType).collect(Collectors.toList());
        List<Integer> templateGoodsType = new ArrayList<>();
        settlement.getCouponAndTemplateInfos().forEach(ct -> {
            templateGoodsType.addAll(JSON.parseObject(
                    ct.getTemplateSDK().getRule().getUsage().getGoodsType(),
                    List.class
            ));
        });
        //如果想要使用多类优惠券，则必须要所有的商品类型都包含在内，即差集为空


        return CollectionUtils.isEmpty(CollectionUtils.subtract(
                goodsType,templateGoodsType
        ));
    }

    @Override
    public SettlementInfo computeRule(SettlementInfo settlement) {

        double goodsSum = retain2Decimals(goodsCostSum(
                settlement.getGoodsInfos()
        ));
        SettlementInfo probability = processGoodsTypeNotSatisfy(
                settlement,goodsSum
        );
        if(probability != null){
            log.debug("Manjian And ZheKou Template Is Not Match To GoodsType");
            return probability;
        }
        SettlementInfo.CouponAndTemplateInfo manJian = null;
        SettlementInfo.CouponAndTemplateInfo zhekou = null;

        for(SettlementInfo.CouponAndTemplateInfo ct:
        settlement.getCouponAndTemplateInfos()){
            if(CouponCategory.of(ct.getTemplateSDK().getCategory()) ==
                    CouponCategory.MANJIAN){
                manJian = ct;
            }else{
                zhekou = ct;
            }
        }
        assert null != manJian;
        assert null != zhekou;

        //当前的优惠券和满减券如果不能共用(一起使用),清空优惠券，返回商品原价
        if(!isTemplateCanShared(manJian,zhekou)){
            log.debug("Current ManJian And ZheKou Can Not Shared!");
            settlement.setCost(goodsSum);
            settlement.setCouponAndTemplateInfos(Collections.emptyList());
        }
        List<SettlementInfo.CouponAndTemplateInfo> ctInfos = new ArrayList<>();
        double manjainBase = (double)manJian.getTemplateSDK().getRule()
                .getDiscount().getQuota();
        double manJianQuota = (double)manJian.getTemplateSDK().getRule()
                .getDiscount().getQuota();
        //最终的价格
        double targetSum = goodsSum;
        if(targetSum >= manjainBase){
            targetSum -= manJianQuota;
            ctInfos.add(manJian);
        }
        //再计算折扣
        double zheKouQuota = (double) zhekou.getTemplateSDK().getRule()
                .getDiscount().getQuota();
        targetSum *= zheKouQuota * 1.0 /100;
        ctInfos.add(zhekou);

        settlement.setCouponAndTemplateInfos(ctInfos);
        settlement.setCost(retain2Decimals(
                targetSum > minCost() ? targetSum : minCost()
        ));
        log.debug("Use ManJian And ZheKou Coupon Make Goods Cost From {} To {}",
                goodsSum,settlement.getCost());

        return settlement;
    }

    private boolean isTemplateCanShared(SettlementInfo.CouponAndTemplateInfo manJian,
                                        SettlementInfo.CouponAndTemplateInfo zheKou) {
        String manjianKey = manJian.getTemplateSDK().getKey()
                + String.format("%04d", manJian.getTemplateSDK().getId());
        String zhekouKey = zheKou.getTemplateSDK().getKey()
                + String.format("%04d", zheKou.getTemplateSDK().getId());
        List<String> allSharedKeysForManjian = new ArrayList<>();
        allSharedKeysForManjian.add(manjianKey);
        allSharedKeysForManjian.addAll(JSON.parseObject(
                manJian.getTemplateSDK().getRule().getWeight(),
                List.class
        ));
        List<String> allSharedKeyForZheKou = new ArrayList<>();
        allSharedKeyForZheKou.add(zhekouKey);
        allSharedKeyForZheKou.addAll(JSON.parseObject(
                zheKou.getTemplateSDK().getRule().getWeight(),
                List.class
        ));
        return CollectionUtils.isSubCollection(Arrays.asList(manjianKey, zhekouKey),
                allSharedKeysForManjian)
                || CollectionUtils.isSubCollection(
                       Arrays.asList(manjianKey,zhekouKey),allSharedKeyForZheKou
        );
    }
}
